package com.project.controller;

import com.common.annotation.Anonymous;
import com.common.annotation.Excel;
import com.common.core.controller.BaseController;
import com.common.core.domain.AjaxResult;
import com.common.core.page.TableDataInfo;
import com.common.utils.CurrentRoleUtils;
import com.common.utils.SecurityUtils;
import com.common.utils.poi.ExcelUtil;
import com.github.pagehelper.PageHelper;
import com.project.comom.NumberDealUtils;
import com.project.domain.dto.projectApplyDto.*;
import com.project.domain.dto.projectCheckDto.SearchExcelReqDto;
import com.project.domain.dto.projectReviewDto.LixiangReqDto;
import com.project.domain.entity.BizProjectApplyInfo;
import com.project.domain.vo.BizProjectAppBookBudgetFeeSaveVo;
import com.project.domain.vo.BizProjectApplyBookVo;
import com.project.domain.vo.BizProjectApplyInfoVo;
import com.project.service.IProjectApplyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;


/**
 * Created by cw13031 on 2025/2/6.
 * Description:
 */

@RestController
@RequestMapping("/project/apply")
public class ProjectApplyController  extends BaseController{

    @Autowired
    IProjectApplyService projectApplyService;

    /**\
     * Deprecated  统一前端，将get改为post。该接口废弃
     * @param bizProjectApplyInfoVo x
     * @return x
     */
    @Deprecated
    @GetMapping(value = "/list")
    public TableDataInfo list( BizProjectApplyInfoVo bizProjectApplyInfoVo)
    {
        startPage();
        System.out.println(bizProjectApplyInfoVo);
        List<HashMap<String,Object>> list =projectApplyService.list(bizProjectApplyInfoVo);

        return getDataTable(list);
    }

    /**
     * Deprecated  统一前端，将get改为post。该接口废弃
     * 左上方统计 全部 未启动 申请中 已停止
     * @param bizProjectApplyInfoVo 检索参数
     * @return AjaxResult
     */
    @Deprecated
    @GetMapping(value = "/list-statistics")
    public AjaxResult listStatistics( BizProjectApplyInfoVo bizProjectApplyInfoVo)
    {
        List<HashMap<String, Integer>> list =projectApplyService.listStatistics(bizProjectApplyInfoVo);

        return success(list);
    }

    @PostMapping(value = "/list")
    public TableDataInfo listV2(@RequestBody BizProjectApplyInfoVo vo)
    {
        //region 分页参数在body的处理方式。尽管是PostMapping，但是分页参数还是建议写在url上，以便ruoyi框架处理。实体类需要指定排序默认值
        /*
          String orderBy = SqlUtil.escapeOrderBySql(vo.getOrderByColumn()) + " " + vo.getIsAsc();
                  PageHelper.startPage(vo.getPageNum(), vo.getPageSize(), orderBy);
         */
        //endregion
        // 专家只可见 申请中和已停止的项目
        vo.setRoleKey(CurrentRoleUtils.getCurrentRoleKey());
        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        List<HashMap<String,Object>> list =projectApplyService.list(vo);
        return getDataTable(list);
    }


    @PostMapping(value = "/list-statistics")
    public AjaxResult listStatisticsV2(@RequestBody  BizProjectApplyInfoVo bizProjectApplyInfoVo)
    {
        bizProjectApplyInfoVo.setRoleKey(CurrentRoleUtils.getCurrentRoleKey());
        List<HashMap<String, Integer>> list =projectApplyService.listStatistics(bizProjectApplyInfoVo);

        return success(list);
    }

    @PostMapping(value = "/add")
    public AjaxResult add(@RequestBody BizProjectApplyInfo bizProjectApplyInfo)
    {
        projectApplyService.add(bizProjectApplyInfo);
        return success();
    }

    @GetMapping(value = "/view")
    public AjaxResult view(@ModelAttribute BizProjectApplyInfo bizProjectApplyInfo) {
        String id = bizProjectApplyInfo.getId();
        if (!StringUtils.hasText(id)){return error("id 字段不能为空");}

        ApplyInfoViewResDto res = projectApplyService.getApplyInfoById(id);

        String fileId = res.getFileId();
        if (StringUtils.hasText(fileId)){

            String[] fileIds = fileId.split(",");
            ArrayList<HashMap<String,String>> fileInfo = projectApplyService.getFileInfoByFileIds(fileIds);
            res.setFileList(fileInfo);
        }
        return success(res);
    }

    @PostMapping(value = "/edit")
    public AjaxResult edit(@RequestBody BizProjectApplyInfo bizProjectApplyInfo)
    {
        projectApplyService.edit(bizProjectApplyInfo);
        return success();
    }

    @PostMapping(value = "/delete")
    public AjaxResult delete(@RequestBody HashMap<String,List<String>> args)
    {
        List<String> ids = args.get("ids");
        if (ids.size()>0){
            projectApplyService.delete(ids);
        }
        return success();
    }

    @PostMapping(value = "/changeState")
    public AjaxResult changeState(@RequestBody BizProjectApplyInfo bizProjectApplyInfo)
    {
        projectApplyService.changeState(bizProjectApplyInfo);
        return success();
    }

    /**
     * 申请材料
     * @param bizProjectApplyBookVo
     * @return x
     */
    @PostMapping(value = "/materials/add")
    public AjaxResult materialsAdd(@RequestBody BizProjectApplyBookVo bizProjectApplyBookVo)
    {
        projectApplyService.materialsAdd(bizProjectApplyBookVo);
        return success();
    }


    @GetMapping(value = "/materials/info")
    public AjaxResult getInfo(@ModelAttribute BizProjectApplyBookVo bizProjectApplyBookVo) {
//        return success(projectApplyService.getBookByBooId(bizProjectApplyBookVo));
        HashMap<String, Object> res = projectApplyService.getBookByBooId(bizProjectApplyBookVo);

        String fileId = res.get("uploadFileId").toString();
        if (StringUtils.hasText(fileId)){

            String[] fileIds = fileId.split(",");
            ArrayList<HashMap<String,String>> fileInfo = projectApplyService.getFileInfoByFileIds(fileIds);
            res.put("fileInfo",fileInfo);
        }
        return success(res);
    }

    @PostMapping(value = "/materials/info")
    public AjaxResult saveInfo(@RequestBody BizProjectApplyBookVo bizProjectApplyBookVo)
    {
        String id = projectApplyService.materialsSaveInfo(bizProjectApplyBookVo);
        HashMap<String, Object> map = new HashMap<>();
        map.put("id",id);
        return success(map);
    }

    @GetMapping(value = "/materials/member")
    public AjaxResult getMember(@ModelAttribute BizProjectApplyBookVo bizProjectApplyBookVo) {
        List<HashMap<String, Object>> members = projectApplyService.materialsGetMember(bizProjectApplyBookVo);
        BizProjectApplyBookVo book = projectApplyService.getApplyBookByBookId(bizProjectApplyBookVo);

        if (book == null) {
            return error("查询不到book");
        }

        HashMap<String, Object> map = new HashMap<>();
        map.put("applierId",book.getApplierId());
        map.put("name",book.getName());
        map.put("applierName",book.getApplierName());
        map.put("applyFee",book.getApplyFee());
        map.put("members",members);
        return success(map);
    }

    @PostMapping(value = "/materials/member")
    public AjaxResult saveMember(@RequestBody BizProjectApplyBookVo bizProjectApplyBookVo)
    {
        projectApplyService.materialsSaveMember(bizProjectApplyBookVo);
        return success();
    }

    /**
     *
     * @param projectTypeCode x
     * @param projectStartDate x
     * @param applyBookId x
     * @deprecated 该接口需要除了applyBookId的额外参数，其实那些参数不需要。
     * 新接口只需要applyBookId，{@link #getBudgetV2(String)}
     * @return x
     */
    @Deprecated
    @GetMapping(value = "/materials/budget")
    public AjaxResult getBudget(
            @RequestParam String projectTypeCode,
            @RequestParam String projectStartDate,
            @RequestParam String applyBookId
    ) {
        // 查询预算树
        List<HashMap<String,Object>> res = projectApplyService.getBudget(projectTypeCode,projectStartDate,applyBookId);
        // 查询book信息
        BizProjectApplyBookVo bizProjectApplyBookVo = new BizProjectApplyBookVo();
        bizProjectApplyBookVo.setId(applyBookId);
        BizProjectApplyBookVo book = projectApplyService.getApplyBookByBookId(bizProjectApplyBookVo);
        if (book==null){ return error("applyBookId不存在"); }
        //拼接结构
        HashMap<String, Object> map = new HashMap<>();
        map.put("name",book.getName());
        map.put("applierName",book.getApplierName());
        map.put("applyFee",book.getApplyFee());
        map.put("budget",res);
        return success(map);
    }

    @GetMapping(value = "/materials/budget-v2")
    public AjaxResult getBudgetV2(
            @RequestParam String applyBookId
    ) {
        // 查询预算树
        List<HashMap<String,Object>> res = projectApplyService.getBudgetV2(applyBookId);
        // 查询book信息
        BizProjectApplyBookVo bizProjectApplyBookVo = new BizProjectApplyBookVo();
        bizProjectApplyBookVo.setId(applyBookId);
        BizProjectApplyBookVo book = projectApplyService.getApplyBookByBookId(bizProjectApplyBookVo);
        if (book==null){ return error("applyBookId不存在"); }
        //拼接结构
        HashMap<String, Object> map = new HashMap<>();
        map.put("name",book.getName());
        map.put("applierName",book.getApplierName());
        map.put("applyFee",book.getApplyFee());
        map.put("budget",res);
        return success(map);
    }

    @PostMapping(value = "/materials/budget")
    public AjaxResult saveBudget(@RequestBody BizProjectAppBookBudgetFeeSaveVo bizProjectApplyBookVo)
    {

        projectApplyService.saveBudget(bizProjectApplyBookVo);
        return success();
    }


    /**
     *
     * @param args
     * @return
     * @deprecated 该方法已被废弃，因为book状态已由流程引擎接管
     */
    @PostMapping(value = "/book/state")
    @Deprecated
    public AjaxResult changeBookState(@RequestBody ChangeBookStateDto args)
    {
        projectApplyService.changeBookState(args);
        return success();
    }

    @PostMapping(value = "/book/del")
    public AjaxResult deleteBook(@RequestBody HashMap<String,List<String>> args)
    {
        List<String> ids = args.get("ids");
        if (ids.size()>0){
            projectApplyService.deleteBook(ids);
        }
        return success();
    }


    @PostMapping(value = "/lixiang")
    public AjaxResult lixiang(@RequestBody LixiangReqDto dto)
    {
        int res = projectApplyService.lixiang(dto);
//        List<String> ids = args.get("ids");
//        if (ids.size()>0){
//            projectApplyService.deleteBook(ids);
//        }
        return success();
    }


    @PostMapping(value = "/history")
    public TableDataInfo history(@RequestBody ApplyHistoryReqDto dto)
    {
        //region 根据角色类型，进行不同的条件查询
        dto.setRoleKey(CurrentRoleUtils.getCurrentRoleKey());
        dto.setUserId(SecurityUtils.getUserRealId());

        String unitAdminScopeReal = SecurityUtils.getLoginUser().getUser().getUnitAdminScopeReal();
        if (unitAdminScopeReal==null){
            // 没有管理任何部门
            dto.setUnitScope(new ArrayList<>());
        }else {
            // 本人有管理部门
            dto.setUnitScope(new ArrayList<>(Arrays.asList(SecurityUtils.getLoginUser().getUser().getUnitAdminScopeReal().split(","))));
        }
        //endregion
        PageHelper.startPage(dto.getPageNum(), dto.getPageSize(), dto.getOrderBy());
        ArrayList<ApplyHistoryResDto> res =  projectApplyService.applyHistory(dto);
        return getDataTable(res);
    }


    @GetMapping(value = "/i-join")
    public TableDataInfo i_join(@ModelAttribute IJoinReqDto dto)
    {
        ArrayList<IJoinResDto> res =  projectApplyService.i_join(dto);
        return getDataTable(res);
    }

    /**
     * 导出excel之前获取可选字段
     * @param dto x
     * @return x
     */
    @GetMapping(value = "/getExcelFields")
    public AjaxResult getExcelFields(@ModelAttribute ExcelFieldsReqDto dto)
    {
        String page = dto.getPage();
        ArrayList<HashMap<String, String>> li = new ArrayList<>();
        Field[] fields;
        if ("apply".equals(page)){
             fields = ExportHistoryApplyBookMybatisDto.class.getDeclaredFields();
        }
        else if ("review".equals(page) || "passedBooks".equals(page)){
            fields = ExportApplyBookMybatisDto.class.getDeclaredFields();
        }else {
            return error("page参数异常");
        }

        for (Field field : fields) {
            // 检查字段是否带有 @ExcelProperty 注解
            if (field.isAnnotationPresent(Excel.class)) {
                HashMap<String, String> map = new HashMap<>();
                Excel excelProperty = field.getAnnotation(Excel.class);
                String fieldName = field.getName(); // 获取字段名，如 "projectName"
                String fieldShow = excelProperty.name(); // 获取注解中的 name 值，如 "项目名称"
                map.put("field", fieldName);
                map.put("showName", fieldShow);
                li.add(map);
            }
        }
        return success(li);
    }

    /**
     * 申报材料导出（有条件导出）
     * @param dto x
     */
    @PostMapping(value = "/exportExcel")
    public void exportExcel(HttpServletResponse response, @RequestBody ApplyHistoryExcelReqDto dto)
    {
        //region 根据角色类型，进行不同的条件查询
        dto.setRoleKey(CurrentRoleUtils.getCurrentRoleKey());
        dto.setUserId(SecurityUtils.getUserRealId());

        String unitAdminScopeReal = SecurityUtils.getLoginUser().getUser().getUnitAdminScopeReal();
        if (unitAdminScopeReal==null){
            // 没有管理任何部门
            dto.setUnitScope(new ArrayList<>());
        }else {
            // 本人有管理部门
            dto.setUnitScope(new ArrayList<>(Arrays.asList(SecurityUtils.getLoginUser().getUser().getUnitAdminScopeReal().split(","))));
        }
        //endregion

        ArrayList<ExportHistoryApplyBookMybatisDto> dataList = projectApplyService.exportHistoryApplyExcel(dto);
        //region 元-->万元
        for (ExportHistoryApplyBookMybatisDto o : dataList) {
            o.setApplyFee(NumberDealUtils.divide_10000(o.getApplyFee()));
        }
        //endregion
        ExcelUtil<ExportHistoryApplyBookMybatisDto> util = new ExcelUtil<>(ExportHistoryApplyBookMybatisDto.class);
        util.showColumn(dto.getCols().toArray(new String[0]));
        util.exportExcel(response, dataList, "申报材料列表");
    }

    /**
     * 管理员-项目申报-查看申报-导出
     * @param response x
     * @param dto x
     */
    @PostMapping(value = "/exportBookExcel")
    public void exportBookExcel(HttpServletResponse response, @RequestBody SearchExcelReqDto dto)
    {
        ArrayList<ExportApplyBookMybatisDto> dataList = projectApplyService.exportBookExcel(dto);
        //region 元-->万元
        for (ExportApplyBookMybatisDto o : dataList) {
            o.setApplyFee(NumberDealUtils.divide_10000(o.getApplyFee()));
        }
        //endregion
        ExcelUtil<ExportApplyBookMybatisDto> util = new ExcelUtil<>(ExportApplyBookMybatisDto.class);
        util.showColumn(dto.getCols().toArray(new String[0]));
        util.exportExcel(response, dataList, "基本科研业务费项目申报材料导出");
    }


    /**
     * 由于流程引擎的启用，该接口只有会在1种场景被调用
     * ①科研人员首次申请book时，一鼓作气直接提交时
     * @param dto x
     * @return x
     */
    @PostMapping(value = "/book/submit")
    public AjaxResult bookSubmit(@RequestBody BookSubmitDto dto)
    {
        projectApplyService.bookSubmit(dto);
        return success();
    }
}
